#include <Python.h>
#include <stdio.h>

class CFoo
{
public:
    CFoo()
    {
        printf("Ctor...\n");
    }

    ~CFoo()
    {
        printf("Dtor...\n");
    }

    void func()
    {
        printf("method func...\n");
    }
};

// SWIG style wrappers
static PyObject * new_CFoo(PyObject *self, PyObject *args)
{
    PyObject * resultObj = 0;
    
    CFoo *obj = new CFoo;
    
    resultObj = (PyObject *)(void *)obj;
    
    return resultObj;
}

static PyObject * delete_CFoo(PyObject *self, PyObject *args)
{
    //delete f;
    return 0;
}

static PyObject * CFoo_func(PyObject *self, PyObject *args)
{
    //f->func();
    return 0;
}

static PyObject * foo_init(PyObject *self, PyObject *args)
{
    printf("foo.__init__ called\n");
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject * foo_doSomething(PyObject *self, PyObject *args)
{
    printf("foo.doSomething called\n");
    Py_INCREF(Py_None);
    return Py_None;
}

static PyMethodDef fooMethods[] =
{
    {"__init__", foo_init, METH_VARARGS, "init"},
    {"doSomething", foo_doSomething, METH_VARARGS, "doSomething"},
    {NULL}
};

static PyMethodDef moduleMethods[] =
{
    {"new_CFoo", new_CFoo, METH_NOARGS},
    {"delete_CFoo", delete_CFoo, METH_NOARGS},
    {"CFoo_func", CFoo_func, METH_NOARGS},
    {NULL}
};

#ifdef __cplusplus
extern "C"
#endif // __cplusplus
PyMODINIT_FUNC
initfoo()
{
    PyMethodDef *def;

    /* */
    PyObject *module = Py_InitModule("foo", moduleMethods);
    PyObject *moduleDict = PyModule_GetDict(module);
    PyObject *classDict = PyDict_New();
    PyObject *className = PyString_FromString("foo");
    PyObject *fooClass = PyClass_New(NULL, classDict, className);
    PyDict_SetItemString(moduleDict, "foo", fooClass);
    Py_DECREF(classDict);
    Py_DECREF(className);
    Py_DECREF(fooClass);

    for (def = fooMethods; def->ml_name != NULL; ++def)
    {
        PyObject *func = PyCFunction_New(def, NULL);
        PyObject *method = PyMethod_New(func, NULL, fooClass);
        PyDict_SetItemString(classDict, def->ml_name, method);
        Py_DECREF(func);
        Py_DECREF(method);
    }

}
